/*
 *  usmap.js
 *
 *  This file has these main responsibilities:
 *  1. Initialize the main page, index.html.
 *  2. Setup all the listeners for the main page.
 *  3. Grab values of HTML elements for other parts of the application.
 *
 *  @author Tanya L. Crenshaw
 */
define(['./utilities', './filterMenu', './admissions', './layers'], function(utilities, filterMenu, admissions, layers) 
{
	/*
	 *  lookup()
	 *
	 *  For an array of layers, this function filters the layers
	 *  according to the input grabbed from the page (that is,
	 * 	entered by the user) and recenters the layer's map at the area
	 *  indicated by the input.
	 *
	 *  This function assumes that all the layers are on the same map.
	 *  Thus, when resetting the zoom and recentering the map, these
	 *  operations are done only once on the first layer.
	 *
	 *  @param layerArray An array of Google FusionTableLayers.
	 *  @param geocoder The geocoder service to use to recenter the map.
	 *  @return void
	 */
	var lookup = function(layerArray, geocoder) 
	{
		// Get the CEEB code from the page, as entered by the user.
		var lookup = utilities.getLookup();
		var lookupType = utilities.getLookupType();

		// Did the user type anything?
		if(lookup == "") 
		{
			// Give an error message to the user:
			utilities.getErrorMsgElement().innerHTML = "Error: Please enter a Lookup";
		}
		// Did the user enter the CEEB?
		else if (lookupType === "CEEB")
		{
			lookupCEEB(lookup, layerArray, geocoder);
		}
		else if (lookupType == "High School Name")
		{
			lookupHighSchool(lookup, layerArray, geocoder);
		}
		else if (lookupType === "City")
		{
			//Calls getTopThree to set topThreeCeebs to the top three schools
			getTopThree("City", lookup);
			
			// Filter each layer by the region.
			utilities.forEach(layerArray, function(t) 
			{
				layers.filterByCity.call(t, lookup);
			});
			
			// Set the zoom.
			layerArray[0].map.setZoom(10);

			// Center the map at the state corresponding to the region.
			centerAt(layerArray[0].map, lookup, geocoder);
		}
		else if (lookupType === "Zip Code")
		{
			//Calls getTopThree to set topThreeCeebs to the top three schools
			getTopThree("Zip", lookup);
			
			// Filter each layer by the region.
			utilities.forEach(layerArray, function(t) 
			{
				layers.filterByZip.call(t, lookup);
			});
			// Set the zoom.
			layerArray[0].map.setZoom(11);

			// Center the map at the state corresponding to the region.
			centerAt(layerArray[0].map, lookup, geocoder);
		}
		else if (lookupType === "State")
		{
			//Calls getTopThree to set topThreeCeebs to the top three schools
			getTopThree("State", admissions.convertRegionToState(lookup));

			// Filter each layer by the region.
			utilities.forEach(layerArray, function(t) 
			{
				layers.filterByRegion.call(t, lookup);
			});
			// Set the zoom.
			layerArray[0].map.setZoom(6);

			// Center the map at the state corresponding to the region.
			centerAt(layerArray[0].map, admissions.convertRegionToState(lookup), geocoder);
		}
	};
	
	/*
	 *  lookupCEEB()
	 *
	 *  This helper function for lookup() focuses on if the user
	 *  inputted a CEEB code.
	 * 
	 *  @param lookup The inputted CEEB code
	 *  @param layerArray An array of Google FusionTableLayers.
	 *  @param geocoder The geocoder service to use to recenter the map.
	 *  @return void
	 */
	var lookupCEEB = function(lookup, layerArray, geocoder)
	{
		// Clear any error message.
		utilities.getErrorMsgElement().innerHTML = "";
		
		//console.log(admissions.ceebToHighSchool(lookup));

		// Get the corresponding zipcode for this CEEB.  The zipcode for this
		// CEEB is contained in the same row as the CEEB in the Google Fusion
		// tables.  So, I need to get the Zip in the row whose 'Code' is
		// the CEEB entered by the user.  This is done using the GET API
		// specified in the Google Fusion Tables Developer documentation.

		// Create a url for a subsequent GET request to a Google server.
		var query = "SELECT * FROM 1TysRKf1siV396AMbUKmi8w2-XB3Zeye2ObXjl8Y WHERE Code = " + lookup;

		var url = "https://www.googleapis.com/fusiontables/v1/query";
		url = url + "?sql=";
		url = url + query;
		url = url + " &key=" + apikey;

		utilities.getRightSidebarElement().innerHTML = "";
		function handleResponse1() 
		{
			if(httpRequest.readyState === 4) 
			{
				if(httpRequest.status === 200) 
				{
					// The code reaches this point because the Google server
					// responded with some useful data.

					// The response is just a string.  I need
					// to parse it so that I can extract the zip code from it.
					var response = JSON.parse(httpRequest.responseText);

					if(response["rows"] != undefined) 
					{
						// Set 	the zoom.
						layerArray[0].map.setZoom(11);

						var highSchoolName = admissions.getHighSchoolName(response);
						var highSchoolAddress = admissions.getHighSchoolAddress(response);
						var zipcode = admissions.getZipcode(response);

						// Center the map.
						centerAt(layerArray[0].map, zipcode, geocoder);

						// Filter the zip layer by zip
						layers.filterByZip.call(layerArray[0], zipcode);

						// Filter the school layer by CEEB.
						layers.filterByCEEB.call(layerArray[1], lookup);

						// Display the textual result
						utilities.getRightSidebarElement().innerHTML += '<p><u>' + highSchoolName + '    CEEB: ' + lookup + '</u></p>';
						
						//Display the stats of the school
						getStats(new Array(lookup), 0);
					} 
					else 
					{
						// Indicate to the user that I could not find that CEEB.
						utilities.getRightSidebarElement().innerHTML += "Cannot locate CEEB: " + lookup + ".";
					}
				}
			}
		}
		
		// Send the GET Request to the Google Server
		utilities.sendRequest(url, handleResponse1);
	};
	
	/*
	 *  getStats()
	 *
	 *  Given a ceeb code, access all the data associated with that code
	 *  and calculate the average GPA, math SAT, and verbal SAT scores of
	 *  the students who applied to UP.  We also keep track of how many
	 *  "sneaky apps" are from that ceeb.
	 *
	 *  @param ceebArray The array of ceeb codes to get the data for
	 *	@param type The type of lookup that's happening.  Changes how we display the stats.
	 *				0 = An individual school is being displayed.
	 *				1 = The top three are being displayed
	 *  @param highSchoolNames The array of high school names.  Only used for type 1.
	 *  @return void
	 */
	var getStats = function(ceebArray, type, highSchoolNames)
	{
		//This code constructs the url we will use to search for the High School Codes
		var apikey = "AIzaSyAa3T_3Acc6RgmIVYNzIWm-vmKsmOpI7Zg";
		
		var url = "https://www.googleapis.com/fusiontables/v1/query?sql=SELECT * FROM 13na5H4_enS7_zftNnAhsd1JWpgDBVv6tg5P_624 WHERE ";
		url = url + " HighSchoolCode = '" + ceebArray[0] + "' &key=";
		url = url + apikey;
		
		var processStats = function() 
		{
			if(httpRequest.readyState === 4)
			{
				if(httpRequest.status === 200) 
				{
					//data is all of the data
					var data = JSON.parse(httpRequest.responseText);
					
					var row = 0;
					var total = 0;
					var avgGPA = 0, countGPA = 0;
					var avgVerb = 0, countVerb = 0;
					var avgMath = 0, countMath = 0;
					var applied = 0;
					var enrolled = 0;
					var accepted = 0;
					var waitlisted = 0;
					var rejected = 0;
					var deposits = 0;
					var sneakers = 0;
					var UPV = 0, AVJ = 0, SVD = 0;
					
					for(row = 0; row < data.rows.length; row++) 
					{
						nextStudent = data.rows[row];
						
						if(!isNaN(nextStudent[3]))//3 is GPA
						{
							avgGPA += parseInt(nextStudent[3]);
							countGPA += 1;
						}
						if(!isNaN(nextStudent[4]))//4 is SAT_Verbal
						{
							avgVerb += parseInt(nextStudent[4]);
							countVerb += 1;
						}
						if(!isNaN(nextStudent[5])) //5 is SAT_Math
						{
							avgMath += parseInt(nextStudent[5]);
							countMath += 1;
						}
						if(nextStudent[6] === "") //6 is First contact with University
							sneakers += 1;
							
						// X is Admit Cancelled
						// R is denied
						// W is waitlisted
						// A is accepted without cancel
						if(nextStudent[9] === "A") //9 is App_Decision_Code
							accepted += 1;
						else if(nextStudent[9] === "W") //9 is App_Decision_Code
							waitlisted += 1;
						else if(nextStudent[9] === "R") //9 is App_Decision_Code
							rejected += 1;
						if(nextStudent[9] !== "") //9 is App_Decision_Code
							applied += 1;
						if(nextStudent[10] === "CONF") //10 is Confirmed
							deposits += 1;
						if(nextStudent[11] === "Y") //11 is Enrolled
							enrolled += 1;
						
						//Calculate the totals of different visitation types
						if(nextStudent[24] === "UPV") //UPV = Visited campus
							UPV += 1;
						else if(nextStudent[24] === "AVJ") //AVJ = Admissions Visitation day
							AVJ += 1;
						else if(nextStudent[24] === "SVD") //SVD = Saturday visit
							SVD += 1;
						total += 1;
					}
					
					var pAccepted = (accepted / total)*100;
					var pWaitlisted = (waitlisted / total)*100;
					var pRejected = (rejected / total)*100;
					var pDeposits = (deposits / total)*100;
					var pEnrolled = (enrolled / total)*100;
					var pApplied = (applied / total)*100;
					var pVisited = ((UPV + AVJ + SVD) / total)*100;
					var pUPV = (UPV / total)*100;
					var pAVJ = (AVJ / total)*100;
					var pSVD = (SVD / total)*100;
					var pSneakers = (sneakers / total)*100;
									
					avgGPA = avgGPA / countGPA;
					avgVerb = avgVerb / countVerb;
					avgMath = avgMath / countMath;
					
					if(type == 0)
					{
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_1"><u>Application Status Stats:</u></p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">Number of Students: ' + total + '</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">Applied: ' + applied + ' (' + pApplied.toFixed(2) + '%)</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">Accepted: ' + accepted + ' (' + pAccepted.toFixed(2) + '%)</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">Waitlisted: ' + waitlisted + ' (' + pWaitlisted.toFixed(2) + '%)</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">Rejected: ' + rejected + ' (' + pRejected.toFixed(2) + '%)</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">Deposits: ' + deposits + ' (' + pDeposits.toFixed(2) + '%)</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">Enrolled: ' + enrolled + ' (' + pEnrolled.toFixed(2) + '%)</p>';
						
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_1"><u>Visitation Stats:</u></p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">Total visited: ' + (UPV + AVJ + SVD) + ' (' + pVisited.toFixed(2) + '%)</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">UPV: ' + UPV + ' (' + pUPV.toFixed(2) + '%)</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">AVJ: ' + AVJ + ' (' + pAVJ.toFixed(2) + '%)</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">SVD: ' + SVD + ' (' + pSVD.toFixed(2) + '%)</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">Sneakers: ' + sneakers + ' (' + pSneakers.toFixed(2) + '%)</p>';
						
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_1">Average GPA: ' + avgGPA.toFixed(2) + '</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_1">Average SAT Math: ' + avgMath.toFixed(2) + '</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_1">Average SAT Verbal: ' + avgVerb.toFixed(2) + '</p>';
					}
					else if(type == 1)
					{
						//Display less information since there's less room.
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_1">' + highSchoolNames[0] + '  CEEB: ' + ceebArray[0] + '</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">Applied: ' + applied + ' (' + pApplied.toFixed(2) + '%)</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">Accepted: ' + accepted + ' (' + pAccepted.toFixed(2) + '%)</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">Enrolled: ' + enrolled + ' (' + pEnrolled.toFixed(2) + '%)</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">Total visited: ' + (UPV + AVJ + SVD) + ' (' + pVisited.toFixed(2) + '%)</p>';
						utilities.getRightSidebarElement().innerHTML += '<p id="tabbed_2">Sneakers: ' + sneakers + ' (' + pSneakers.toFixed(2) + '%)</p>';
						
						ceebArray.shift();
						highSchoolNames.shift();
						
						//Recursively make another http request on the next school
						if(ceebArray != undefined)
						{
							getStats(ceebArray, type, highSchoolNames);
						}
					}
				}
			}
		};
		
		utilities.sendRequest(url, processStats);
	};
	
	/*
	 *  getTopThree()
	 *
	 *  This function takes a lookupType (state or zip) and a lookup
	 *  and finds the best three schools in that region, in terms of the
	 *  number of prospective students from that school.
	 *
	 *  @param lookupType A string telling whether this is a State or Zip
	 *  @param lookup The State or Zip we search for
	 *  @return void
	 */
	var getTopThree = function(lookupType, lookup) 
	{
		//This code constructs the url we will use to search for the High School Codes
		var apikey = "AIzaSyAa3T_3Acc6RgmIVYNzIWm-vmKsmOpI7Zg";
		
		var url = "https://www.googleapis.com/fusiontables/v1/query?sql=SELECT 'HighSchoolCode' FROM 13na5H4_enS7_zftNnAhsd1JWpgDBVv6tg5P_624 WHERE ";
		
		url = url + lookupType + " = '" + lookup + "' &key=";
		url = url + apikey;
		
		//This function is designed to get all of the ceebs, and select the  of them
		//that appear most in the data, and set the global varaible to them.
		var processData = function() 
		{
			if(httpRequest.readyState === 4)
			{
				if(httpRequest.status === 200) 
				{
					//data is all of the ceebs
					var data = JSON.parse(httpRequest.responseText);
					var ceebs = new Array();
					var applicantQuantity = {};
					var currentApplicant = "";
			
					//This function uses applicantQuantity as a sort of hash
					//to develop a set of arrays to find the top three schools
					for(var row = 0; row < data.rows.length; row++) 
					{
						nextCeeb = data.rows[row][0];
						if(applicantQuantity[nextCeeb] === undefined)
						{
							applicantQuantity[nextCeeb] = 1;
							ceebs.push(nextCeeb);
						}
						else
						{
							applicantQuantity[nextCeeb]++;
						}
					}
					
					//This is very inelloquent, and we need to go back and make this better
					//but currently it goes through, and if a ceeb is better than the top
					//one it sets itself to that and waterfalls 1 to 2 and 2 to 3, etc.
					bestCeeb1 = "";
					bestCeebQuantity1 = 0;
					bestCeeb2 = "";
					bestCeebQuantity2 = 0;
					bestCeeb3 = "";
					bestCeebQuantity3 = 0;
					
					for(var i = 0; i < ceebs.length; i++)
					{
						currentApplicant = ceebs[i];
						if(applicantQuantity[currentApplicant] > bestCeebQuantity3 && !isNaN(currentApplicant))
						{
							if(applicantQuantity[currentApplicant] > bestCeebQuantity2)
							{
								if(applicantQuantity[currentApplicant] > bestCeebQuantity1)
								{
									bestCeeb3 = bestCeeb2;
									bestCeebQuantity3 = bestCeebQuantity2;
									bestCeeb2 = bestCeeb1;
									bestCeebQuantity2 = bestCeebQuantity1;
									bestCeeb1 = currentApplicant;
									bestCeebQuantity1 = applicantQuantity[currentApplicant];
								}
								else
								{
									bestCeeb3 = bestCeeb2;
									bestCeebQuantity3 = bestCeebQuantity2;
									bestCeeb2 = currentApplicant;
									bestCeebQuantity2 = applicantQuantity[currentApplicant];
								}
							}
							else
							{
								bestCeeb3 = currentApplicant;
								bestCeebQuantity3 = applicantQuantity[currentApplicant];
							}
						}
					}
					
					utilities.getRightSidebarElement().innerHTML = "<p><u>Top 3 High Schools for Applications:</u></p>";
					
					topThreeCeebs = new Array();
					topThreeCeebs.push(bestCeeb1);
					topThreeCeebs.push(bestCeeb2);
					topThreeCeebs.push(bestCeeb3);
					
					//Loop through the best CEEBs and display the high school names associated with them
					convertCEEBtoHighSchool(topThreeCeebs);
				}
			}
		};
		
		utilities.sendRequest(url, processData);
	};
	
	/*
	 *  lookupHighSchool()
	 *
	 *  This helper function for lookup() focuses on if the user
	 *  inputted a high school name.
	 *
	 *  This lookup is slightly different in that it must also include the state
	 *  due to severe repetition in high school names.  So it should follow
	 *  the format:
	 *  High School Name, State
	 * 
	 *  @param name The inputted high school name along with the state
	 *  @param layerArray An array of Google FusionTableLayers.
	 *  @param geocoder The geocoder service to use to recenter the map.
	 *  @return void
	 */
	var lookupHighSchool = function(name, layerArray, geocoder)
	{
		state = name.substring(name.indexOf(",") + 2);
		name = name.substring(0, name.indexOf(","));
		
		var apikey = "AIzaSyAa3T_3Acc6RgmIVYNzIWm-vmKsmOpI7Zg";
		// Get the corresponding zipcode for this CEEB.  The zipcode for this
		// CEEB is contained in the same row as the CEEB in the Google Fusion
		// tables.  So, I need to get the Zip in the row whose 'Code' is
		// the CEEB entered by the user.  This is done using the GET API
		// specified in the Google Fusion Tables Developer documentation.

		// Create a url for a subsequent GET request to a Google server.
		var query = "SELECT Code, HighSchoolName FROM 1UV9a8FlmJ8HihP2YlAB3Uw5XA17ZJDBWIUQZET4 WHERE HighSchoolName = ";
		name = name.toUpperCase();
		state = admissions.convertRegionToState(state);
		query += "'" + name + "' AND State = '" + state + "'";

		var url = "https://www.googleapis.com/fusiontables/v1/query?sql=" + query + " &key=" + apikey;
		
		var highSchooltoCEEB = function() 
		{
			if(httpRequest.readyState === 4) 
			{
				if(httpRequest.status === 200) 
				{
					// The code reaches this point because the Google server
					// responded with some useful data.

					// The response is just a string, so it needs to be parsed.
					var response = JSON.parse(httpRequest.responseText);
					//console.log(response.rows[0][0]);
					var ceeb = response.rows[0][0];
					lookupCEEB(ceeb, layerArray, geocoder);
				}
			}
		};
		utilities.sendRequest(url, highSchooltoCEEB);
	};
	
	/*
	 *  convertCEEBtoHighSchool()
	 *
	 *	Given a set of ceebs, this method converts them to High Schools and get the stats
	 * for them, and has them displayed in the app.
	 *
	 *  @param ceebArray  A string representing the ceeb to be converted.
	 *
	 *  @return void
	 * 
	 */
	var convertCEEBtoHighSchool = function(ceebArray)
	{
			
		
		var schoolNames = new Array();
		console.log(ceebArray.length);
		for(i = 0; i < ceebArray.length; i++)
		{
			console.log(ceebArray[i]);
			highSchoolName = admissions.ceebToHighSchool(ceebArray[i]);
			schoolNames.push(toTitleCase(highSchoolName));
		}
		getStats(ceebArray, 1, schoolNames);
		
	};
	
	/*
	 *  toTitleCase()
	 *
	 *  Given a string, return the same string but title-cased.
	 *  For example, the inputted string "hELlo WOrld" would be returned
	 *  as "Hello World".
	 *
	 *  @param str The string to be title-cased.
	 *  @return The title-cased string.
	 */
	var toTitleCase = function(str)
	{
		return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
	};
	
	/*
	 *  centerAt()
	 *
	 *	Given an address, use the Google geocode service to obtain the
	 *  latitude and longitude points for that address and center the
	 *  window object's 'map' at the lat/lon point provided.
	 *
	 *  Note that the Google geocoder service is an asynchronous call,
	 *  so an anonymous callback function is used to handle the result.
	 *  Otherwise, the page will hang.
	 *
	 *  Based largely on the geocode sample provided in the Google Developer
	 *  documentation for Google Maps API 3 for Javascript.
	 *
	 *  @param address A string representing an address, such as "Chicago"
	 *  or "92171"
	 *  @return void
	 */
	var centerAt = function(map, address, geocoder) 
	{
		geocoder.geocode(
		{
			'address' : address + ", USA"
		}, function(results, status) 
		{
			if(status == google.maps.GeocoderStatus.OK) 
			{
				map.setCenter(results[0].geometry.location);
			} 
			else 
			{
				alert("Geocode was not successful for the following reason: " + status);
			}
		});
	};
	
	/*
	 *  regionalize()
	 *
	 *  This function filters an array of layer objects based on the
	 *  region name grabbed from the page (that is, entered by the user)
	 *  and recenters the map at the region.
	 *
	 *  @param layerArray An array of Layer objects to regionalize.
	 *  @param geocoder The geocoder service to use to recenter the map.
	 *  @return void
	 */
	var regionalize = function(layerArray, geocoder) 
	{
		// Get the region name from the page, as entered by the user.
		var region = utilities.getLookupType();

		// Filter each layer by the region.
		utilities.forEach(layerArray, function(t) 
		{
			layers.filterByRegion.call(t, region);
		});
		// Set the zoom.
		layerArray[0].map.setZoom(6);

		// Center the map at the state corresponding to the region.
		centerAt(layerArray[0].map, admissions.convertRegionToState(region), geocoder);
	};
	
	/*
	 *  initialize()
	 *
	 *  A function to:
	 *  1. create a google map centered at the us
	 *  2. Initialize two layer objects, one for zipcodes and one for schools.
	 *  3. instantiate a google maps geocoder service.
	 *
	 *  @param void
	 *  @return void
	 */
	var initialize = function() 
	{
		// Set the Google API key for this namespace.
		apikey = 'AIzaSyAa3T_3Acc6RgmIVYNzIWm-vmKsmOpI7Zg';

		// Create the httpRequestor for this namespace.
		utilities.makeRequestor();

		// Encrypted IDs for the Google Fusion Table containing the
		// Oregon high school and CEEB data.
		var schoolEID = '1TysRKf1siV396AMbUKmi8w2-XB3Zeye2ObXjl8Y';

		// The Encrypted ID used below is that of tl_2010_41_zcta051_clean.kml
		// available in Tanya Crenshaw's public fusion tables.
		var zipEID = '1U6n-9O6I9q4qG10uNcNrCAlvactfL7O07IVPLbU';

		// Instatiate a new geocoder service
		var geocoder = new google.maps.Geocoder();

		// The center point of the map is Lincoln, NB.
		var usa = new google.maps.LatLng(40.8358, -96.6452);

		// Create a Google Map object centered at usa
		var map = new google.maps.Map(document.getElementById("contig_us_map_canvas"), 
		{
			zoom : 4,
			center : usa,
			mapTypeId : google.maps.MapTypeId.ROADMAP
		});
		//
		//	Construct the layers
		//
		// Create a Layer object for the zip code boundary layer.  The second parameter
		// creates the Google FusionTablesLayer object.  The Layer is not currently being
		// filtered, so the final parameter is false.
		var zipLayer = new layers.Layer("zips", new google.maps.FusionTablesLayer(
		{
			query : 
			{
				from : zipEID
			}
		}), zipEID, map, 'ZipCodeArea', false);

		// Create a Layer object for the high schools layer.  The second parameter
		// creates the Google FusionTablesLayer object.  The Layer is not currently being
		// filtered, so the final parameter is false.
		var schoolLayer = new layers.Layer("schools", new google.maps.FusionTablesLayer(
		{
			query : 
			{
				from : schoolEID
			}
		}), schoolEID, map, 'Zip', false);

		// Create an array of Layers
		var layerArray = new Array();
		layerArray.push(zipLayer);
		layerArray.push(schoolLayer);

		// Attach the function lookup() to the lookupButton on the main page.
		utilities.addEvent(document.getElementById('lookupButton'), 'click', function() 
		{
			return lookup(layerArray, geocoder);
		});
		//
		// Constructing the Filter Menus
		//
		// Create the Region Filtering menu
		// Connect the filter menu to the "regionFilterPanel" that is on the index.html page.
		// Get the menu options from the admissions domain model method, getRegions().
		// Attach the method filter() to the menu such that whenever the menu changes,
		// the filter() method is called.
		var regionFilterMenu = new filterMenu.FilterMenu("regionFilterMenu", "regionFilterMenu", "filterMenu", "regionFilterPanel", admissions.getRegions(), function() 
		{
			return regionalize(layerArray, geocoder);
		});
		regionFilterMenu.createMenu();
		
		//Create the HashTable for Ceebs and HighSchoolNames
		var query = "SELECT Code, HighSchoolName FROM 1UV9a8FlmJ8HihP2YlAB3Uw5XA17ZJDBWIUQZET4 ";
		var url = "https://www.googleapis.com/fusiontables/v1/query?sql=" + query + " &key=" + apikey;
		
		var createAdmissionsHash = function() 
		{
			if(httpRequest.readyState === 4) 
			{
				if(httpRequest.status === 200) 
				{
					// The code reaches this point because the Google server
					// responded with some useful data.

					// The response is just a string, so it needs to be parsed.
					var response = JSON.parse(httpRequest.responseText);
					//console.log(response.rows[0][0]);
					admissions.createCeebHash(response);
				}
			}
		};
		utilities.sendRequest(url, createAdmissionsHash);
		
	};
	
	// Any functions defined in this return statement are considered public
	// functions by RequireJS, and accessible through the namespace that
	// is attached to this module when loaded in other files.
	return {
		lookup : lookup,
		lookupCEEB : lookupCEEB,
		getStats : getStats,
		getTopThree : getTopThree,
		lookupHighSchool : lookupHighSchool,
		convertCEEBtoHighSchool : convertCEEBtoHighSchool,
		toTitleCase : toTitleCase,
		centerAt : centerAt,
		regionalize : regionalize,
		initialize : initialize
	};
});
